#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <json/json.h>
#include "Utility.hpp"

#define SEP " "
#define SEP_LEN strlen(SEP)
#define HEADSEP "\r\n"
#define HEADSEP_LEN strlen(HEADSEP)
// #define MYSEP 1

/*
   const & : 输入
        *  : 输出
        &  : 输入输出
*/
namespace pr
{
    // 添加报头：判断有效载荷是否完整
    //"10 + 20"-->"7\r\n"10 + 20"\r\n"  报头 + 有效载荷
    std::string AddHeader(std::string &str)
    {
        std::cout << "AddHeader 之前:\n"
                  << str << std::endl;
        std::string tmp = std::to_string(str.size()) + HEADSEP + str + HEADSEP;
        std::cout << "AddHeader 之后:\n"
                  << tmp << std::endl;
        return tmp;
    }
    std::string RemoveHeader(std::string &str, int len)
    {
        std::cout << "RemoveHeader 之前:\n"
                  << str << std::endl;
        std::string tmp = str.substr(str.size() - HEADSEP_LEN - len, len);
        std::cout << "RemoveHeader 之后:\n"
                  << tmp << std::endl;
        return tmp;
    }

    // 为了获取单个完整的报文"7\r\n"10 + 20"\r\n"
    // 处理细节：添加一个string缓冲区存储从sock中读取的数据，防止前一次读取的数据丢失
    //判断是否是完整报文
    int BackPacket(std::string &Inffer, std::string *packet)
    {
        auto pos = Inffer.find(HEADSEP);
        if (pos == std::string::npos)
            return 0; // 此文件中没有报文
        std::string LenStr = Inffer.substr(0, pos);
        int len = atoi(LenStr.c_str());
        int targetpacketlen = LenStr.size() + len + 2 * HEADSEP_LEN;
        if (Inffer.size() < targetpacketlen)
            return 0;                                // 报文不完整
        *packet = Inffer.substr(0, targetpacketlen); // 获取到单个完整的报文"7\r\n"10 + 20"\r\n"
        Inffer.erase(0, targetpacketlen);            // 将要用的报文处理掉
        std::cout << "ReadPacket Inffer 之后:\n"
                  << Inffer << std::endl;
        return len;
    }
    // 请求
    //序列化和反序列化
    //1)自己手动实现
    //2)用别人的 jsoncpp、protobuf
    class Request
    {
    public:
        Request()
        {
        }
        Request(int x, int y, char op) : _x(x), _y(y), _op(op)
        {
        }
        // 序列化-->"1 + 2"
        bool Serialize(std::string *outStr) // 为什么这个用指针，用引用不行吗？
        {
            *outStr = "";
#ifdef MYSEP
            *outStr = std::to_string(_x) + SEP + _op + SEP + std::to_string(_y);
            std::cout << "Request Serialize:" << *outStr << std::endl;
#else
          Json::Value root;  //Value:一种万能对象，接收任意的kv类型
          root["x"] = _x;
          root["y"] = _y;
          root["op"] = _op;
        //   Json::FastWriter writer; //FastWriter:是用来进行序列化的 struct->string
        Json::StyledWriter writer;
          *outStr = writer.write(root);
#endif
            return true;
        }

        // 反序列化
        //"1 + 2"
        // 用vector<string>向量储存数据:[0]->_x   [1]->_y  [2]->_op
        // string-->struct
        bool Deserialize(const std::string &inStr)
        {
#ifdef MYSEP
            std::vector<std::string> result;
            Util::StringSplit(inStr, SEP, &result);
            if (result.size() != 3) // 判断序列化的数据是否正确，也防止后续的代码越界操作
                return false;
            if (result[1].size() != 1) // 判断序列化的数据是否正确，也防止后续的代码越界操作
                return false;
            _x = Util::ToInt(result[0]);
            _y = Util::ToInt(result[2]);
            _op = result[1][0];
            Print();
#else
          Json::Value root;
          Json::Reader reader;  //Reader用来进行反序列化的
          reader.parse(inStr,root);
          
          _x = root["x"].asInt();
          _y = root["y"].asInt();
          _op = root["op"].asInt();
#endif
            return true;
        }
        void Print()
        {
            std::cout << "_x=" << _x << std::endl;
            std::cout << "_y=" << _y << std::endl;
            std::cout << "_z=" << _op << std::endl;
        }
        ~Request() {}

    public:
        int _x;
        int _y;
        char _op;
    };

    // 响应
    class Response
    {
    public:
        Response() : _result(0), _code(0)
        {
        }
        //_result  _code
        bool Serialize(std::string *outStr) // 为什么这个用指针，用引用不行吗？将结果提出来
        {
            *outStr = "";
#ifdef MYSEP
            *outStr = std::to_string(_result) + SEP + std::to_string(_code);
            std::cout << "Response Serialize:" << *outStr << std::endl;
#else
          Json::Value root;  //Value:一种万能对象，接收任意的kv类型
          root["result"] = _result;
          root["code"] = _code;
        //   Json::FastWriter writer; //FastWriter:是用来进行序列化的 struct->string
         Json::StyledWriter writer;
          *outStr = writer.write(root);
#endif
            return true;
        }
        bool Deserialize(const std::string &inStr)
        {
#ifdef MYSEP
            std::vector<std::string> result;
            Util::StringSplit(inStr, SEP, &result);
            if (result.size() != 2) // 判断序列化的数据是否正确，也防止后续的代码越界操作
                return false;
            _result = Util::ToInt(result[0]);
            _code = Util::ToInt(result[1]);
            Print();
#else
          Json::Value root;
          Json::Reader reader;  //Reader用来进行反序列化的
          reader.parse(inStr,root);
          
          _result = root["result"].asInt();
          _code = root["code"].asInt();
#endif
            return true;
        }
        void Print()
        {
            std::cout << "_result=" << _result << std::endl;
            std::cout << "_code=" << _code << std::endl;
        }
        ~Response()
        {
        }

    public:
        int _result;
        int _code; // 0:success; 1,2,3,4其他错误码
    };
}